package com.example.myapplication.base;


import android.animation.Animator;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;

import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;


import java.util.List;

/**
 * Fragment基类。
 *
 */
public class UIFragment extends Fragment {

    @Nullable
    UIFragmentManager mFragmentManager;
    @Nullable
    UITransitionAnimation mPopAnimation;

    private final UIFragmentController mFragments = new UIFragmentController(new HostCallback());

    @Nullable
    private Context mAppContext;
    private int mResultCode;
    @Nullable
    private Bundle mResultData;

    protected String pushTag ;  // 设置此tag可以让fragment不被detach，默认不设置。

    public String getPushTag() {
        return pushTag;
    }

    public void setPushTag(String tag) {
        this. pushTag = tag;
    }

    @Override
    public void onAttach(@NonNull Context context) {
        LogEvent.fragment(getLogTag(), "onAttach");
        mAppContext = context.getApplicationContext();
        super.onAttach(context);
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        LogEvent.fragment(getLogTag(), "onConfigurationChanged");
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onContextItemSelected(@NonNull MenuItem item) {
        LogEvent.fragment(getLogTag(), "onContextItemSelected");
        return super.onContextItemSelected(item);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        LogEvent.fragment(getLogTag(), "onCreate");
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
        // 动画相关内容，注释后无影响，使用默认动画。
        /*
        final Fragment parentFragment = getParentFragment();
        if (parentFragment != null) {
            final Animation animation = new AlphaAnimation(1f, 1f);
            if (enter && !parentFragment.isResumed()) {
                animation.setDuration(0);
                return animation;
            }
            boolean removing = !enter
                    && (parentFragment.isDetached() || parentFragment.isRemoving());
            if (removing) {
                animation.setDuration(Long.MAX_VALUE);
                return animation;
            }
        }*/
        LogEvent.fragment(getLogTag(), "onCreateAnimation");
        return super.onCreateAnimation(transit, enter, nextAnim);
    }

    @Nullable
    @Override
    public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
        LogEvent.fragment(getLogTag(), "onCreateAnimator");
        return super.onCreateAnimator(transit, enter, nextAnim);
    }

    @Override
    public void onCreateContextMenu(@NonNull ContextMenu menu, @NonNull View v,
                                    @Nullable ContextMenu.ContextMenuInfo menuInfo) {
        LogEvent.fragment(getLogTag(), "onCreateContextMenu");
        super.onCreateContextMenu(menu, v, menuInfo);
    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        LogEvent.fragment(getLogTag(), "onCreateOptionsMenu");
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        LogEvent.fragment(getLogTag(), "onCreateView");
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onDestroy() {
        LogEvent.fragment(getLogTag(), "onDestroy");
        super.onDestroy();
    }

    @Override
    public void onDestroyOptionsMenu() {
        LogEvent.fragment(getLogTag(), "onDestroyOptionsMenu");
        super.onDestroyOptionsMenu();
    }

    @Override
    public void onDestroyView() {
        LogEvent.fragment(getLogTag(), "onDestroyView");
        super.onDestroyView();
    }

    @Override
    public void onDetach() {
        LogEvent.fragment(getLogTag(), "onDetach");
        super.onDetach();
    }

    @NonNull
    @Override
    public LayoutInflater onGetLayoutInflater(@Nullable Bundle savedInstanceState) {
        LogEvent.fragment(getLogTag(), "onGetLayoutInflater");
        return super.onGetLayoutInflater(savedInstanceState);
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        LogEvent.fragment(getLogTag(), "onHiddenChanged", hidden);
        super.onHiddenChanged(hidden);
    }

    @Override
    public void onInflate(@NonNull Context context, @NonNull AttributeSet attrs,
                          @Nullable Bundle savedInstanceState) {
        LogEvent.fragment(getLogTag(), "onInflate");
        super.onInflate(context, attrs, savedInstanceState);
    }

    @Override
    public void onLowMemory() {
        LogEvent.fragment(getLogTag(), "onLowMemory");
        super.onLowMemory();
    }

    @Override
    public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
        LogEvent.fragment(getLogTag(), "onMultiWindowModeChanged");
        super.onMultiWindowModeChanged(isInMultiWindowMode);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        LogEvent.fragment(getLogTag(), "onOptionsItemSelected");
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onOptionsMenuClosed(@NonNull Menu menu) {
        LogEvent.fragment(getLogTag(), "onOptionsMenuClosed");
        super.onOptionsMenuClosed(menu);
    }

    @Override
    public void onPause() {
        LogEvent.fragment(getLogTag(), "onPause");
        super.onPause();
    }

    @Override
    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
        LogEvent.fragment(getLogTag(), "onPictureInPictureModeChanged");
        super.onPictureInPictureModeChanged(isInPictureInPictureMode);
    }

    @Override
    public void onPrepareOptionsMenu(@NonNull Menu menu) {
        LogEvent.fragment(getLogTag(), "onPrepareOptionsMenu");
        super.onPrepareOptionsMenu(menu);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        LogEvent.fragment(getLogTag(), "onRequestPermissionsResult");
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public void onResume() {
        LogEvent.fragment(getLogTag(), "onResume");
        super.onResume();
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        LogEvent.fragment(getLogTag(), "onSaveInstanceState");
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onStart() {
        LogEvent.fragment(getLogTag(), "onStart");
        super.onStart();
    }

    @Override
    public void onStop() {
        LogEvent.fragment(getLogTag(), "onStop");
        super.onStop();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        LogEvent.fragment(getLogTag(), "onViewCreated");
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        LogEvent.fragment(getLogTag(), "onViewStateRestored");
        super.onViewStateRestored(savedInstanceState);
    }

    /**
     * 当用户点击返回键，且所有子Fragment都没有消费此次点击事件时，此方法将会被调用。
     *
     * @return {@code true}表示消费此次点击事件，事件将停止传递，{@code false}表示不消费此次点击事件，
     * Fragment的默认返回逻辑将会被执行。
     * @see #onBackPressed
     */
    protected boolean onBack() {
        LogEvent.fragment(getLogTag(), "onBack");
        return false;
    }

    /**
     * 当用户点击返回键，此方法将会被调用。
     * <p>
     * 此方法首先向子Fragment传递点击事件。如果所有子Fragment没有消费掉点击事件，那么{@link #onBack}方法将会被
     * 调用。如果{@link #onBack}方法也没有消费掉点击事件，那么Fragment的默认返回逻辑将会被执行。
     *
     * @return {@code true}表示消费此次点击事件，事件将停止传递，{@code false}表示不消费此次点击事件，事件将继
     * 续传递。
     * @see #onBack
     */
    public boolean onBackPressed() {
        LogEvent.fragment(getLogTag(), "onBackPressed");
        return mFragments.onBackPressed() || onBack() || popFragment() != null;
    }

    /**
     * 当Fragment退出时回调。
     *
     * @param requestCode 由{@link #pushFragmentForResult}方法传入的请求码，用于确认是谁发起的请求。
     * @param resultCode  上一个Fragment通过{@link #setResult(int)}方法传入的结果码。
     * @param data        上一个Fragment通过{@link #setResult(int, Bundle)}方法传入的结果{@link Bundle}
     *                    对象，如果没有的话则为{@code null}。
     */
    protected void onFragmentResult(int requestCode, int resultCode, @Nullable Bundle data) {
        LogEvent.fragment(getLogTag(), "onFragmentResult", requestCode, resultCode, data);
    }

    /**
     * 获取Application context对象。
     *
     * @return Application context对象，如果在Fragment第一次附加到Activity之前调用则返回{@code null}。
     */
    @Nullable
    public Context getApplicationContext() {
        return mAppContext;
    }

    /**
     * 获取Application context对象。
     *
     * @return Application context对象。
     * @throws IllegalStateException 如果在Fragment第一次附加到Activity之前调用。
     */
    @NonNull
    public Context requireApplicationContext() {
        final Context context = getApplicationContext();
        if (context == null) {
            throw new IllegalStateException("UIFragment " + this + " has not been attached yet.");
        }
        return context;
    }

    /**
     * 获取{@link Window}对象。
     *
     * @return {@link Window}对象，如果Fragment没有附加到Activity，或者Activity不是可见的，则返回
     * {@code null}。
     */
    @Nullable
    public Window getWindow() {
        final Activity activity = getActivity();
        return activity == null ? null : activity.getWindow();
    }

    /**
     * 获取{@link ActionBar}对象。
     *
     * @return {@link ActionBar}对象，如果Fragment没有附加到Activity，或者Activity不是
     * {@link AppCompatActivity}类型的，或者Activity没有ActionBar，则返回{@code null}。
     */
    @Nullable
    public ActionBar getActionBar() {
        final Activity activity = getActivity();
        return activity instanceof AppCompatActivity ?
                ((AppCompatActivity) activity).getSupportActionBar() : null;
    }

    /**
     * 设置结果码，将会在Fragment退出时返回给调用者。
     *
     * @param resultCode 结果码。
     */
    public final void setResult(int resultCode) {
        setResult(resultCode, null);
    }

    /**
     * 设置结果码和结果{@link Bundle}对象，将会在Fragment退出时返回给调用者。
     *
     * @param resultCode 结果码。
     * @param data       结果{@link Bundle}对象，如果没有的话可以传入{@code null}。
     */
    public final void setResult(int resultCode, @Nullable Bundle data) {
        mResultCode = resultCode;
        mResultData = data;
    }

    /**
     * 启动一个新的Activity。
     *
     * @param cls 需要启动的Activity类。
     * @see #startActivityForResult
     */
    public void startActivity(@NonNull Class<?> cls) {
        ArgUtils.checkNonNull("cls", cls);
        startActivity(new Intent(requireContext(), cls));
    }

    /**
     * 启动一个新的Activity，并在其返回后回调结果。
     *
     * @param cls         需要启动的Activity类。
     * @param requestCode 请求码，如果大于或等于0的话，会在Activity返回后，在{@link #onActivityResult}中返
     *                    回。
     * @see #startActivity
     */
    public void startActivityForResult(@NonNull Class<?> cls, int requestCode) {
        ArgUtils.checkNonNull("cls", cls);
        startActivityForResult(new Intent(requireContext(), cls), requestCode);
    }

    /**
     * 通过标签查找Fragment对象。
     *
     * @param tag Fragment标签。
     * @return Fragment对象，如果当前Fragment没有附加到Activity，或者未找到对应的Fragment则返回
     * @deprecated 查找的fragment是按照入栈顺序的，如果多实例的情况下，往往会不符合要求.
     * @see FragmentManager#findFragmentByTag
     * {@code null}。
     */
    @Nullable
    @Deprecated
    public Fragment findFragmentByTag(@Nullable String tag) {
        final FragmentManager fragmentManager = getFragmentManager();
        return fragmentManager == null ? null : fragmentManager.findFragmentByTag(tag);
    }

    /**
     * 通过标签查找子Fragment对象。
     *
     * @param tag Fragment标签。
     * @return Fragment对象，如果未找到对应的Fragment则返回{@code null}。
     * @see FragmentManager#findFragmentByTag
     */
    @Nullable
    public Fragment findChildFragmentByTag(@Nullable String tag) {
        return getChildFragmentManager().findFragmentByTag(tag);
    }

    /**
     * 获取当前Fragment所在容器的Fragment管理器。
     *
     * @return Fragment管理器，如果Fragment没有与之关联的管理器则返回{@code null}。
     */
    @Nullable
    public UIFragmentManager getUIFragmentManager() {
        return mFragmentManager;
    }

    /**
     * 获取当前Fragment所在容器的Fragment管理器。
     *
     * @return Fragment管理器。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @NonNull
    public UIFragmentManager requireUIFragmentManager() {
        final UIFragmentManager fragmentManager = getUIFragmentManager();
        if (fragmentManager == null) {
            throw new IllegalStateException("UIFragment " + this + " not associated with a UIFragmentManager.");
        }
        return fragmentManager;
    }

    /**
     * 弹出一个新的Fragment。
     *
     * @param cls 需要弹出的Fragment类。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragment(@NonNull Class<? extends UIFragment> cls) {
        return pushFragment(new UIFragmentInfo(cls));
    }

    /**
     * 弹出一个新的Fragment。
     *
     * @param cls 需要弹出的Fragment类。
     * @param tag Fragment标签，或者传入{@code null}不设标签。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragment(@NonNull Class<? extends UIFragment> cls,
                                   @Nullable String tag) {
        return pushFragment(new UIFragmentInfo(cls, tag));
    }

    /**
     * 弹出一个新的Fragment。
     *
     * @param fragmentInfo Fragment信息。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragment(@NonNull UIFragmentInfo fragmentInfo) {
        return pushFragment(fragmentInfo, null);
    }

    /**
     * 弹出一个新的Fragment。
     *
     * @param cls         需要弹出的Fragment类。
     * @param transaction Fragment弹出跳转参数，或者传入{@code null}使用默认参数。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragment(@NonNull Class<? extends UIFragment> cls,
                                   @Nullable UIPushTransaction transaction) {
        return pushFragment(new UIFragmentInfo(cls), transaction);
    }

    /**
     * 弹出一个新的Fragment。
     *
     * @param cls         需要弹出的Fragment类。
     * @param tag         Fragment标签，或者传入{@code null}不设标签。
     * @param transaction Fragment弹出跳转参数，或者传入{@code null}使用默认参数。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragment(@NonNull Class<? extends UIFragment> cls,
                                   @Nullable String tag,
                                   @Nullable UIPushTransaction transaction) {
        return pushFragment(new UIFragmentInfo(cls, tag), transaction);
    }


    @Nullable
    public UIFragment pushFragment(@NonNull UIFragmentInfo fragmentInfo,
                                   @Nullable UIPushTransaction transaction) {
        return requireUIFragmentManager().push(fragmentInfo, transaction);
    }

    /**
     * 弹出一个新的Fragment。
     *
     * @param newFragment 新的Fragment对象。
     * @return {@code true}表示弹出成功，{@code false}表示弹出失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean pushFragment(@NonNull UIFragment newFragment) {
        return pushFragment(newFragment, null, null);
    }

    /**
     * 弹出一个新的Fragment。
     *
     * @param newFragment 新的Fragment对象。
     * @param tag         Fragment标签，或者传入{@code null}不设标签。
     * @return {@code true}表示弹出成功，{@code false}表示弹出失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean pushFragment(@NonNull UIFragment newFragment,
                                @Nullable String tag) {
        return pushFragment(newFragment, tag, null);
    }

    /**
     * 弹出一个新的Fragment。
     *
     * @param newFragment 新的Fragment对象。
     * @param transaction Fragment弹出跳转参数，或者传入{@code null}使用默认参数。
     * @return {@code true}表示弹出成功，{@code false}表示弹出失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean pushFragment(@NonNull UIFragment newFragment,
                                @Nullable UIPushTransaction transaction) {
        return pushFragment(newFragment, null, transaction);
    }

    /**
     * 弹出一个新的Fragment。
     *
     * @param newFragment 新的Fragment对象。
     * @param tag         Fragment标签，或者传入{@code null}不设标签。
     * @param transaction Fragment弹出跳转参数，或者传入{@code null}使用默认参数。
     * @return {@code true}表示弹出成功，{@code false}表示弹出失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean pushFragment(@NonNull UIFragment newFragment,
                                @Nullable String tag,
                                @Nullable UIPushTransaction transaction) {
        return requireUIFragmentManager().push(newFragment, tag, transaction);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param cls         需要弹出的Fragment类。
     * @param requestCode 请求码，如果大于或等于0的话，会在Fragment返回后，在{@link #onFragmentResult}中返
     *                    回。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragmentForResult(@NonNull Class<? extends UIFragment> cls,
                                            int requestCode) {
        return pushFragmentForResult(new UIFragmentInfo(cls), requestCode);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param cls         需要弹出的Fragment类。
     * @param tag         Fragment标签，或者传入{@code null}不设标签。
     * @param requestCode 请求码，如果大于或等于0的话，会在Fragment返回后，在{@link #onFragmentResult}方法
     *                    中返回。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragmentForResult(@NonNull Class<? extends UIFragment> cls,
                                            @Nullable String tag,
                                            int requestCode) {
        return pushFragmentForResult(new UIFragmentInfo(cls, tag), requestCode);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param fragmentInfo Fragment信息。
     * @param requestCode  请求码，如果大于或等于0的话，会在Fragment返回后，回调给{@link #onFragmentResult}
     *                     方法。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragmentForResult(@NonNull UIFragmentInfo fragmentInfo,
                                            int requestCode) {
        return pushFragmentForResult(fragmentInfo, null, requestCode);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param cls         需要弹出的Fragment类。
     * @param transaction Fragment弹出跳转参数，或者传入{@code null}使用默认参数。
     * @param requestCode 请求码，如果大于或等于0的话，会在Fragment返回后，在{@link #onFragmentResult}中返
     *                    回。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragmentForResult(@NonNull Class<? extends UIFragment> cls,
                                            @Nullable UIPushTransaction transaction,
                                            int requestCode) {
        return pushFragmentForResult(new UIFragmentInfo(cls), transaction, requestCode);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param cls         需要弹出的Fragment类。
     * @param tag         Fragment标签，或者传入{@code null}不设标签。
     * @param transaction Fragment弹出跳转参数，或者传入{@code null}使用默认参数。
     * @param requestCode 请求码，如果大于或等于0的话，会在Fragment返回后，在{@link #onFragmentResult}方法
     *                    中返回。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragmentForResult(@NonNull Class<? extends UIFragment> cls,
                                            @Nullable String tag,
                                            @Nullable UIPushTransaction transaction,
                                            int requestCode) {
        return pushFragmentForResult(new UIFragmentInfo(cls, tag), transaction, requestCode);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param fragmentInfo Fragment信息。
     * @param transaction  Fragment弹出跳转参数，或者传入{@code null}使用默认参数。
     * @param requestCode  请求码，如果大于或等于0的话，会在Fragment返回后，回调给{@link #onFragmentResult}
     *                     方法。
     * @return 已弹出的Fragment，如果弹出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment pushFragmentForResult(@NonNull UIFragmentInfo fragmentInfo,
                                            @Nullable UIPushTransaction transaction,
                                            int requestCode) {
        return requireUIFragmentManager().pushForResult(fragmentInfo, transaction, this,
                requestCode);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param newFragment 新的Fragment对象。
     * @param requestCode 请求码，如果大于或等于0的话，会在Fragment返回后，回调给{@link #onFragmentResult}
     *                    方法。
     * @return {@code true}表示弹出成功，{@code false}表示弹出失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean pushFragmentForResult(@NonNull UIFragment newFragment,
                                         int requestCode) {
        return pushFragmentForResult(newFragment, null, null, requestCode);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param newFragment 新的Fragment对象。
     * @param tag         Fragment标签，或者传入{@code null}不设标签。
     * @param requestCode 请求码，如果大于或等于0的话，会在Fragment返回后，回调给{@link #onFragmentResult}
     *                    方法。
     * @return {@code true}表示弹出成功，{@code false}表示弹出失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean pushFragmentForResult(@NonNull UIFragment newFragment,
                                         @Nullable String tag,
                                         int requestCode) {
        return pushFragmentForResult(newFragment, tag, null, requestCode);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param newFragment 新的Fragment对象。
     * @param transaction Fragment弹出跳转参数，或者传入{@code null}使用默认参数。
     * @param requestCode 请求码，如果大于或等于0的话，会在Fragment返回后，回调给{@link #onFragmentResult}
     *                    方法。
     * @return {@code true}表示弹出成功，{@code false}表示弹出失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean pushFragmentForResult(@NonNull UIFragment newFragment,
                                         @Nullable UIPushTransaction transaction, int requestCode) {
        return pushFragmentForResult(newFragment, null, transaction, requestCode);
    }

    /**
     * 弹出一个新的Fragment，并在其返回后回调结果。
     *
     * @param newFragment 新的Fragment对象。
     * @param tag         Fragment标签，或者传入{@code null}不设标签。
     * @param transaction Fragment弹出跳转参数，或者传入{@code null}使用默认参数。
     * @param requestCode 请求码，如果大于或等于0的话，会在Fragment返回后，回调给{@link #onFragmentResult}
     *                    方法。
     * @return {@code true}表示弹出成功，{@code false}表示弹出失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean pushFragmentForResult(@NonNull UIFragment newFragment, @Nullable String tag,
                                         @Nullable UIPushTransaction transaction, int requestCode) {
        return requireUIFragmentManager().pushForResult(newFragment, tag, transaction, this,
                requestCode);
    }

    /**
     * 退出当前Fragment。
     *
     * @return 已退出的Fragment，如果退出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment popFragment() {
        return popFragment(null);
    }

    /**
     * 退出当前Fragment。
     *
     * @param transaction Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return 已退出的Fragment，如果退出失败则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment popFragment(@Nullable UIFragmentTransaction transaction) {
        return requireUIFragmentManager().pop(transaction);
    }

    /**
     * 返回到根Fragment。
     *
     * @return 已退出的Fragment列表，如果退出失败则返回空的列表。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @NonNull
    public List<UIFragment> popToRootFragment() {
        return popToRootFragment(null);
    }

    /**
     * 返回到根Fragment。
     *
     * @param transaction Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return 已退出的Fragment列表，如果退出失败则返回空的列表。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @NonNull
    public List<UIFragment> popToRootFragment(@Nullable UIFragmentTransaction transaction) {
        return requireUIFragmentManager().popToRoot(transaction);
    }

    /**
     * 返回到Fragment。
     *
     * @param fragment 目标Fragment。
     * @return 已退出的Fragment列表，如果退出失败则返回空的列表。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @NonNull
    public List<UIFragment> popToFragment(@NonNull UIFragment fragment) {
        return popToFragment(fragment, null);
    }

    /**
     * 返回到Fragment。
     *
     * @param fragment    目标Fragment。
     * @param transaction Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return 已退出的Fragment列表，如果退出失败则返回空的列表。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @NonNull
    public List<UIFragment> popToFragment(@NonNull UIFragment fragment,
                                          @Nullable UIFragmentTransaction transaction) {
        return requireUIFragmentManager().popTo(fragment, transaction);
    }

    /**
     * 返回到Fragment。
     *
     * @param tag 目标Fragment的标签。
     * @return 已退出的Fragment列表，如果退出失败则返回空的列表。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @NonNull
    public List<UIFragment> popToFragment(@NonNull String tag) {
        return popToFragment(tag, null);
    }

    /**
     * 返回到Fragment。
     *
     * @param tag         目标Fragment的标签。
     * @param transaction Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return 已退出的Fragment列表，如果退出失败则返回空的列表。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @NonNull
    public List<UIFragment> popToFragment(@NonNull String tag,
                                          @Nullable UIFragmentTransaction transaction) {
        return requireUIFragmentManager().popTo(tag, transaction);
    }

    /**
     * 获取当前Fragment所在容器中顶层的Fragment对象。
     *
     * @return 顶层的Fragment对象，如果容器是空的则返回{@code null}。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @Nullable
    public UIFragment getTopFragment() {
        return requireUIFragmentManager().peekTop();
    }

    /**
     * 判断当前Fragment是否位于顶层。
     *
     * @return {@code true}表示当前Fragment在顶层，{@code false}表示当前Fragment不在顶层。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean isTopFragment() {
        return equals(getTopFragment());
    }

    /**
     * 获取当前Fragment所在容器的返回栈。
     *
     * @return 返回栈。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @NonNull
    public List<UIFragment> getBackStack() {
        return requireUIFragmentManager().getBackStack();
    }

    /**
     * 获取当前Fragment所在容器的返回栈大小。
     *
     * @return 返回栈大小。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public int getBackStackCount() {
        return requireUIFragmentManager().getBackStackCount();
    }

    /**
     * 获取当前Fragment所在容器的返回栈内容。
     *
     * @param index 内容索引。
     * @return 返回栈内容。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    @NonNull
    public UIFragment getBackStackAt(int index) {
        return requireUIFragmentManager().getBackStackAt(index);
    }

    /**
     * 判断Fragment是否在当前Fragment所在容器的返回栈中。
     *
     * @param fragment Fragment对象。
     * @return {@code true}表示Fragment在返回栈中，{@code false}表示Fragment不在返回栈中。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean isInBackStack(@Nullable UIFragment fragment) {
        return requireUIFragmentManager().isInBackStack(fragment);
    }

    /**
     * 判断Fragment标签是否在当前Fragment所在容器的返回栈中。
     *
     * @param tag Fragment标签。
     * @return {@code true}表示Fragment标签在返回栈中，{@code false}表示Fragment标签不在返回栈中。
     */
    public boolean isInBackStack(@Nullable String tag) {
        return requireUIFragmentManager().isInBackStack(tag);
    }

    /**
     * 设置当前Fragment所在容器的返回栈。
     *
     * @param backStack 返回栈，不可以是空的，不可以包含{@code null}，不可以包含重复的元素，不可以包含新创建的
     *                  对象。
     * @return {@code true}表示设置成功，{@code false}表示设置失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean setBackStack(@NonNull List<? extends UIFragment> backStack) {
        return setBackStack(backStack, null);
    }

    /**
     * 设置当前Fragment所在容器的返回栈。
     *
     * @param backStack   返回栈，不可以是空的，不可以包含{@code null}，不可以包含重复的元素，不可以包含新创建
     *                    的对象。
     * @param transaction Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return {@code true}表示设置成功，{@code false}表示设置失败。
     * @throws IllegalStateException 如果Fragment没有与之关联的管理器。
     */
    public boolean setBackStack(@NonNull List<? extends UIFragment> backStack,
                                @Nullable UIFragmentTransaction transaction) {
        return requireUIFragmentManager().setBackStack(backStack, transaction);
    }

    /**
     * 获取容器的Fragment管理器。
     *
     * @param containerViewId Fragment容器ID。
     * @return Fragment管理器。
     */
    @NonNull
    public UIFragmentManager getUIFragmentManager(@IdRes int containerViewId) {
        return mFragments.getUIFragmentManager(containerViewId);
    }

    /**
     * 获取容器的默认弹出动画。
     *
     * @param containerViewId Fragment容器ID。
     * @return 默认弹出动画，如果没有的话则返回{@code null}。
     */
    @Nullable
    public UITransitionAnimation getDefaultPushAnimation(@IdRes int containerViewId) {
        return getUIFragmentManager(containerViewId).getDefaultPushAnimation();
    }

    /**
     * 设置容器的默认弹出动画。
     *
     * @param containerViewId Fragment容器ID。
     * @param animation       默认弹出动画，或者传入{@code null}不设默认动画。
     */
    public void setDefaultPushAnimation(@IdRes int containerViewId,
                                        @Nullable UITransitionAnimation animation) {
        getUIFragmentManager(containerViewId).setDefaultPushAnimation(animation);
    }

    /**
     * 获取容器的默认返回动画。
     *
     * @param containerViewId Fragment容器ID。
     * @return 默认返回动画，如果没有的话则返回{@code null}。
     */
    @Nullable
    public UITransitionAnimation getDefaultPopAnimation(@IdRes int containerViewId) {
        return getUIFragmentManager(containerViewId).getDefaultPopAnimation();
    }

    /**
     * 设置容器的默认返回动画。
     *
     * @param containerViewId Fragment容器ID。
     * @param animation       默认返回动画，或者传入{@code null}不设默认动画。
     */
    public void setDefaultPopAnimation(@IdRes int containerViewId,
                                       @Nullable UITransitionAnimation animation) {
        getUIFragmentManager(containerViewId).setDefaultPopAnimation(animation);
    }

    /**
     * 填充Fragment到空的容器中。
     * <p>
     * 如果容器不是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param cls             需要填充的Fragment类。
     * @return 被填充的Fragment对象，如果容器不是空的，或者填充失败则返回{@code null}。
     */
    @Nullable
    public UIFragment setContentFragment(@IdRes int containerViewId,
                                         @NonNull Class<? extends UIFragment> cls) {
        return setContentFragment(containerViewId, new UIFragmentInfo(cls));
    }

    /**
     * 填充Fragment到空的容器中。
     * <p>
     * 如果容器不是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param cls             需要填充的Fragment类。
     * @param tag             Fragment标签，或者传入{@code null}不设标签。
     * @return 被填充的Fragment对象，如果容器不是空的，或者填充失败则返回{@code null}。
     */
    @Nullable
    public UIFragment setContentFragment(@IdRes int containerViewId,
                                         @NonNull Class<? extends UIFragment> cls,
                                         @Nullable String tag) {
        return setContentFragment(containerViewId, new UIFragmentInfo(cls, tag));
    }

    /**
     * 填充Fragment到空的容器中。
     * <p>
     * 如果容器不是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param fragmentInfo    Fragment信息。
     * @return 被填充的Fragment对象，如果容器不是空的，或者填充失败则返回{@code null}。
     */
    @Nullable
    public UIFragment setContentFragment(@IdRes int containerViewId,
                                         @NonNull UIFragmentInfo fragmentInfo) {
        return getUIFragmentManager(containerViewId).setRoot(fragmentInfo);
    }

    /**
     * 填充Fragment到空的容器中。
     * <p>
     * 如果容器不是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param fragment        Fragment对象。
     * @return {@code true}表示设置成功，{@code false}表示设置失败。
     */
    public boolean setContentFragment(@IdRes int containerViewId,
                                      @NonNull UIFragment fragment) {
        return setContentFragment(containerViewId, fragment, null);
    }

    /**
     * 填充Fragment到空的容器中。
     * <p>
     * 如果容器不是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param fragment        Fragment对象。
     * @param tag             Fragment标签，或者传入{@code null}不设标签。
     * @return {@code true}表示设置成功，{@code false}表示设置失败。
     */
    public boolean setContentFragment(@IdRes int containerViewId,
                                      @NonNull UIFragment fragment,
                                      @Nullable String tag) {
        return getUIFragmentManager(containerViewId).setRoot(fragment, tag);
    }

    /**
     * 替换容器中顶层的Fragment。
     * <p>
     * 如果容器是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param cls             需要填充的Fragment类。
     * @return 已替换的Fragment对象，如果容器是空的，或者替换失败则返回{@code null}。
     */
    @Nullable
    public UIFragment replaceTopFragment(@IdRes int containerViewId,
                                         @NonNull Class<? extends UIFragment> cls) {
        return replaceTopFragment(containerViewId, new UIFragmentInfo(cls));
    }

    /**
     * 替换容器中顶层的Fragment。
     * <p>
     * 如果容器是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param cls             需要填充的Fragment类。
     * @param tag             Fragment标签，或者传入{@code null}不设标签。
     * @return 已替换的Fragment对象，如果容器是空的，或者替换失败则返回{@code null}。
     */
    @Nullable
    public UIFragment replaceTopFragment(@IdRes int containerViewId,
                                         @NonNull Class<? extends UIFragment> cls,
                                         @Nullable String tag) {
        return replaceTopFragment(containerViewId, new UIFragmentInfo(cls, tag));
    }

    /**
     * 替换容器中顶层的Fragment。
     * <p>
     * 如果容器是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param fragmentInfo    Fragment信息。
     * @return 已替换的Fragment对象，如果容器是空的，或者替换失败则返回{@code null}。
     */
    @Nullable
    public UIFragment replaceTopFragment(@IdRes int containerViewId,
                                         @NonNull UIFragmentInfo fragmentInfo) {
        return replaceTopFragment(containerViewId, fragmentInfo, null);
    }

    /**
     * 替换容器中顶层的Fragment。
     * <p>
     * 如果容器是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param cls             需要填充的Fragment类。
     * @param transaction     Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return 已替换的Fragment对象，如果容器是空的，或者替换失败则返回{@code null}。
     */
    @Nullable
    public UIFragment replaceTopFragment(@IdRes int containerViewId,
                                         @NonNull Class<? extends UIFragment> cls,
                                         @Nullable UIFragmentTransaction transaction) {
        return replaceTopFragment(containerViewId, new UIFragmentInfo(cls), transaction);
    }

    /**
     * 替换容器中顶层的Fragment。
     * <p>
     * 如果容器是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param cls             需要填充的Fragment类。
     * @param tag             Fragment标签，或者传入{@code null}不设标签。
     * @param transaction     Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return 已替换的Fragment对象，如果容器是空的，或者替换失败则返回{@code null}。
     */
    @Nullable
    public UIFragment replaceTopFragment(@IdRes int containerViewId,
                                         @NonNull Class<? extends UIFragment> cls,
                                         @Nullable String tag,
                                         @Nullable UIFragmentTransaction transaction) {
        return replaceTopFragment(containerViewId, new UIFragmentInfo(cls, tag), transaction);
    }

    /**
     * 替换容器中顶层的Fragment。
     * <p>
     * 如果容器是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param fragmentInfo    Fragment信息。
     * @param transaction     Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return 已替换的Fragment对象，如果容器是空的，或者替换失败则返回{@code null}。
     */
    @Nullable
    public UIFragment replaceTopFragment(@IdRes int containerViewId,
                                         @NonNull UIFragmentInfo fragmentInfo,
                                         @Nullable UIFragmentTransaction transaction) {
        return getUIFragmentManager(containerViewId).replaceTop(fragmentInfo, transaction);
    }

    /**
     * 替换容器中顶层的Fragment。
     * <p>
     * 如果容器是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param fragment        Fragment对象。
     * @return {@code true}表示替换成功，{@code false}表示替换失败。
     */
    public boolean replaceTopFragment(@IdRes int containerViewId,
                                      @NonNull UIFragment fragment) {
        return replaceTopFragment(containerViewId, fragment, null);
    }

    /**
     * 替换容器中顶层的Fragment。
     * <p>
     * 如果容器是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param fragment        Fragment对象。
     * @param tag             Fragment标签，或者传入{@code null}不设标签。
     * @return {@code true}表示替换成功，{@code false}表示替换失败。
     */
    public boolean replaceTopFragment(@IdRes int containerViewId,
                                      @NonNull UIFragment fragment,
                                      @Nullable String tag) {
        return replaceTopFragment(containerViewId, fragment, tag, null);
    }

    /**
     * 替换容器中顶层的Fragment。
     * <p>
     * 如果容器是空的，那么调用此方法将不会产生影响。
     *
     * @param containerViewId Fragment容器ID。
     * @param fragment        Fragment对象。
     * @param tag             Fragment标签，或者传入{@code null}不设标签。
     * @param transaction     Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return {@code true}表示替换成功，{@code false}表示替换失败。
     */
    public boolean replaceTopFragment(@IdRes int containerViewId,
                                      @NonNull UIFragment fragment,
                                      @Nullable String tag,
                                      @Nullable UIFragmentTransaction transaction) {
        return getUIFragmentManager(containerViewId).replaceTop(fragment, tag, transaction);
    }

    /**
     * 清空容器中所有的Fragment
     *
     * @param containerViewId Fragment容器ID
     * @return {@code true}表示清空成功，{@code false}表示清空失败。
     */
    public boolean clearContentFragments(@IdRes int containerViewId) {
        return getUIFragmentManager(containerViewId).clear();
    }

    /**
     * 获取容器中顶层的Fragment对象。
     *
     * @param containerViewId Fragment容器ID。
     * @return 顶层的Fragment对象，如果容器是空的则返回{@code null}。
     */
    @Nullable
    public UIFragment getTopFragment(@IdRes int containerViewId) {
        return getUIFragmentManager(containerViewId).peekTop();
    }

    /**
     * 获取容器的返回栈。
     *
     * @param containerViewId Fragment容器ID。
     * @return 返回栈。
     */
    @NonNull
    public List<UIFragment> getBackStack(@IdRes int containerViewId) {
        return getUIFragmentManager(containerViewId).getBackStack();
    }

    /**
     * 获取容器的返回栈大小。
     *
     * @param containerViewId Fragment容器ID。
     * @return 返回栈大小。
     */
    public int getBackStackCount(@IdRes int containerViewId) {
        return getUIFragmentManager(containerViewId).getBackStackCount();
    }

    /**
     * 获取容器的返回栈内容。
     *
     * @param containerViewId Fragment容器ID。
     * @param index           内容索引。
     * @return 返回栈内容。
     */
    @NonNull
    public UIFragment getBackStackAt(@IdRes int containerViewId, int index) {
        return getUIFragmentManager(containerViewId).getBackStackAt(index);
    }

    /**
     * 判断Fragment是否在容器的返回栈中。
     *
     * @param containerViewId Fragment容器ID。
     * @param fragment        Fragment对象。
     * @return {@code true}表示Fragment在返回栈中，{@code false}表示Fragment不在返回栈中。
     */
    public boolean isInBackStack(@IdRes int containerViewId,
                                 @Nullable UIFragment fragment) {
        return getUIFragmentManager(containerViewId).isInBackStack(fragment);
    }

    /**
     * 判断Fragment标签是否在容器的返回栈中。
     *
     * @param containerViewId Fragment容器ID。
     * @param tag             Fragment标签。
     * @return {@code true}表示Fragment标签在返回栈中，{@code false}表示Fragment标签不在返回栈中。
     */
    public boolean isInBackStack(@IdRes int containerViewId,
                                 @Nullable String tag) {
        return getUIFragmentManager(containerViewId).isInBackStack(tag);
    }

    /**
     * 设置容器的返回栈。
     *
     * @param containerViewId Fragment容器ID。
     * @param backStack       返回栈，不可以是空的，不可以包含{@code null}，不可以包含重复的元素，不可以包含
     *                        新创建的对象。
     * @return {@code true}表示设置成功，{@code false}表示设置失败。
     */
    public boolean setBackStack(@IdRes int containerViewId,
                                @NonNull List<? extends UIFragment> backStack) {
        return setBackStack(containerViewId, backStack, null);
    }

    /**
     * 设置容器的返回栈。
     *
     * @param containerViewId Fragment容器ID。
     * @param backStack       返回栈，不可以是空的，不可以包含{@code null}，不可以包含重复的元素，不可以包含
     *                        新创建的对象。
     * @param transaction     Fragment跳转参数，或者传入{@code null}使用默认参数。
     * @return {@code true}表示设置成功，{@code false}表示设置失败。
     */
    public boolean setBackStack(@IdRes int containerViewId,
                                @NonNull List<? extends UIFragment> backStack,
                                @Nullable UIFragmentTransaction transaction) {
        return getUIFragmentManager(containerViewId).setBackStack(backStack, transaction);
    }


//    @NonNull
//    public MXPreferences getMXPreferences() {
//        return MXPreferenceManager.getPreferences(requireApplicationContext());
//    }


    @Nullable
    public Object getLogTag() {
        return null;
    }

    /**
     * 通知TargetFragment回调
     * @see #pushFragmentForResult(UIFragment, int)
     * @see #onFragmentResult(int, int, Bundle)
     */
    public void notifyFragmentResult() {
        final UIFragment targetFragment = (UIFragment) getTargetFragment();
        if (targetFragment != null) {
            targetFragment.onFragmentResult(getTargetRequestCode(), mResultCode, mResultData);
        }
    }

    /**
     * 恢复所有状态。
     *
     * @param state 状态数据包。
     */
    public void restoreAllState(@Nullable Parcelable state) {
        if (!(state instanceof SavedState)) {
            return;
        }
        mPopAnimation = ((SavedState) state).mPopAnimation;
        mFragments.restoreAllState(((SavedState) state).mFragmentControllerState);
        mResultCode = ((SavedState) state).mResultCode;
        mResultData = ((SavedState) state).mResultData;
    }

    /**
     * 保存所有状态。
     *
     * @return 状态数据包。
     */
    @NonNull
    public Parcelable saveAllState() {
        return new SavedState(this);
    }

    static final class SavedState implements Parcelable {

        @Nullable
        private final UITransitionAnimation mPopAnimation;
        @Nullable
        private final Parcelable mFragmentControllerState;
        private final int mResultCode;
        @Nullable
        private final Bundle mResultData;

        private SavedState(@NonNull UIFragment fragment) {
            mPopAnimation = fragment.mPopAnimation;
            mFragmentControllerState = fragment.mFragments.saveAllState();
            mResultCode = fragment.mResultCode;
            mResultData = fragment.mResultData;
        }

        private SavedState(@NonNull Parcel source, @Nullable ClassLoader loader) {
            mPopAnimation = source.readParcelable(loader);
            mFragmentControllerState = source.readParcelable(loader);
            mResultCode = source.readInt();
            mResultData = source.readBundle(loader);
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeParcelable(mPopAnimation, flags);
            dest.writeParcelable(mFragmentControllerState, flags);
            dest.writeInt(mResultCode);
            dest.writeBundle(mResultData);
        }

        public static final Creator<SavedState> CREATOR = new ClassLoaderCreator<SavedState>() {
            @Override
            public SavedState createFromParcel(Parcel source) {
                return new SavedState(source, null);
            }

            @Override
            public SavedState createFromParcel(Parcel source, ClassLoader loader) {
                return new SavedState(source, loader);
            }

            @Override
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };

    }

    private class HostCallback implements UIFragmentHostCallback {

        @NonNull
        @Override
        public Context getContext() {
            return requireContext();
        }

        @Nullable
        @Override
        public View findViewById(@IdRes int id) {
            return requireView().findViewById(id);
        }

        @NonNull
        @Override
        public FragmentManager getFragmentManager() {
            return getChildFragmentManager();
        }

    }

}
